{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from math import log, sqrt, exp, pi\n",
    "from scipy.stats import norm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class BsmModel:\n",
    "\n",
    "    def __init__(self, option_type, price, strike, interest_rate, expiry, volatility, dividend_yield=0):\n",
    "        self.s = price  # Underlying asset price\n",
    "        self.k = strike  # Option strike K\n",
    "        self.r = interest_rate  # Continuous risk fee rate\n",
    "        self.q = dividend_yield  # Dividend continuous rate\n",
    "        self.T = expiry  # time to expiry (year)\n",
    "        self.sigma = volatility  # Underlying volatility\n",
    "        self.type = option_type # option type \"p\" put option \"c\" call option\n",
    "\n",
    "    def n(self, d):\n",
    "        # cumulative probability distribution function of standard normal distribution\n",
    "        return norm.cdf(d)\n",
    "\n",
    "    def dn(self, d):\n",
    "        # the first order derivative of n(d)\n",
    "        return norm.pdf(d)\n",
    "\n",
    "    def d1(self):\n",
    "        d1 = (log(self.s / self.k) + (self.r - self.q + self.sigma ** 2 * 0.5) * self.T) / (self.sigma * sqrt(self.T))\n",
    "        return d1\n",
    "\n",
    "    def d2(self):\n",
    "        d2 = (log(self.s / self.k) + (self.r - self.q - self.sigma ** 2 * 0.5) * self.T) / (self.sigma * sqrt(self.T))\n",
    "        return d2\n",
    "\n",
    "    def bsm_price(self):\n",
    "        d1 = self.d1()\n",
    "        d2 = d1 - self.sigma * sqrt(self.T)\n",
    "        if self.type == 'c':\n",
    "            price = exp(-self.r*self.T) * (self.s * exp((self.r - self.q)*self.T) * self.n(d1) - self.k * self.n(d2))\n",
    "            return price\n",
    "        elif self.type == 'p':\n",
    "            price = exp(-self.r*self.T) * (self.k * self.n(-d2) - (self.s * exp((self.r - self.q)*self.T) * self.n(-d1)))\n",
    "            return price\n",
    "        else:\n",
    "            print \"option type can only be c or p\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6.1573056407749949"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = BsmModel('c', 42, 35, 0.1, 90.0/365, 0.2)\n",
    "a.bsm_price()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
